package cn.java8practise.behaviorParameterization;

import java.util.ArrayList;
import java.util.List;

/**
 * 行为参数化的具体实例
 * --《java8实战》P31
 * --案例有点类似策略模式，接口是Predicate，具体是策略方法实现代码通过lambda表达式来传递。
 *
 * Created by 杨志远 on 2017/4/18
 * email faryangsh@163.com.
 */
public class AppleDemo{
    public static void main(String[] args) {
        appleTest();
        orageTest();
    }

    private static void appleTest() {

        //构造数据
        List<Apple> apples1 = new ArrayList<>();
        List<Apple> apples2 = new ArrayList<>();
        for (int i = 0; i <10 ; i++) {
            Apple apple1 = Apple.builder()
                    .color(i % 2==1? "red" : "green")
                    .weight(10 * i)
                    .build();
            apples1.add(apple1) ;

            Apple apple2 = Apple.builder()
                    .color(i % 2 == 0 ? "red" : "green")
                    .weight(20 * i)
                    .build();
            apples2.add(apple2);
        }

        //行为参数化，
        List<Apple> list1 = filter(apples1, (Apple apple) -> "red".equals(apple.getColor()));
        List<Apple> list2 = filter(apples2, (Apple apple) -> "red".equals(apple.getColor()) && apple.getWeight()>50 );

        list1.forEach(apple -> System.out.println(apple.toString()));
        list2.forEach(apple -> System.out.println(apple.toString()));
    }

    /**
     * 注释同上
     * --这里是对orage进行测试
     *
     */
    private static void orageTest() {
        List<Orage> orages1 = new ArrayList<>();
        List<Orage> orages2 = new ArrayList<>();
        for (int i = 0; i <10 ; i++) {
            Orage orage1 = Orage.builder()
                    .color(i % 2==1? "red" : "green")
                    .weight(10 * i)
                    .build();
            orages1.add(orage1) ;

            Orage orage2 = Orage.builder()
                    .color(i % 2 == 0 ? "red" : "green")
                    .weight(20 * i)
                    .build();
            orages2.add(orage2);
        }
        List<Orage> list1 = filter(orages1, (Orage orage) -> "red".equals(orage.getColor()));
        List<Orage> list2 = filter(orages1, (Orage orage) -> "red".equals(orage.getColor()) && orage.getWeight()>50 );

        list1.forEach(orage -> System.out.println(orage.toString()));
        list2.forEach(orage -> System.out.println(orage.toString()));
    }

    /**
     * 删选方法
     * --使用泛型使得能够传递不仅仅是Apple，还有Orage
     * --test（）是Predicate抽象方法，具体的实现是其调用者实现的；如果appleTest（）方法中不适用lambda表达式，java8之前的做法是使用匿名内部类。
     *
     * @param list
     * @param p
     * @param <T>
     * @return
     */
    public static <T> List<T> filter(List<T> list,Predicate<T> p){
        List<T> results=new ArrayList<>();
        list.forEach(t -> {
            if (p.test(t)){
                results.add(t);
            }
        });
        return results;
    }

}
